package com.caiyi.financial.nirvana.sms.gateway.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.caiyi.financial.nirvana.sms.entity.SmsReceiveMessage;
import com.caiyi.financial.nirvana.sms.enums.SmsMsgStatusEnum;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.queue.NotifyQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.ReceiveMsgQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.SendQueueEntity;
import com.caiyi.financial.nirvana.sms.util.HttpClientUtil;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.util.*;

public class HaoboGateway extends BaseGateway {

    private static final Logger logger = LoggerFactory.getLogger(HaoboGateway.class);
    //0英文 8ucs2 15中文
    private static final String DC = "15";
    //0不需要状态报告 1需要
    private static final String RD = "1";
    //0内容HEX编码 1内容base64编码 2内容urlEncode编码 3内容urlEncode+utf-8编码
    private static final String TF = "3";
    //成功前缀
    private static final String SUCCESS_PREFIX = "id=";
    //失败前缀
    private static final String FAIL_PREFIX = "r=";
    //状态报告op
    private static final String REPORT = "dr";
    private static final String SUCCESS = "0";
    private static final String[] DCS = {"8", "15"};

    @Override
    public void sendMessage(SendQueueEntity entity) {
        int status = SmsMsgStatusEnum.REQUEST_FAIL.index;
        String result = "";
        try {
            String params = buildParams(entity);
            String url = info.getServerAddr() + params;
            String response = doGet(url);
            if (response == null) {
                result = "网关请求超时";
                return;
            }
            logger.info("HaoboGateway send url : {}, params : {}, result : {}", info.getServerAddr(), params, response);
            if (response.indexOf(SUCCESS_PREFIX) >= 0) {
                status = SmsMsgStatusEnum.REQUEST_SUCCESS.index;
                result = response.substring(response.indexOf(SUCCESS_PREFIX) + SUCCESS_PREFIX.length()).trim();
                JedisService.hset(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, result, entity.getMessageId());
            } else if (response.startsWith(FAIL_PREFIX)) {
                String code = response.substring(FAIL_PREFIX.length()).trim();
                result = code;
            }
        } catch (Exception e) {
            logger.error("HaoboGateway sendMessage error ! ", e);
        } finally {
            onSubmitResponse(status, entity.getMessageId(), result);
        }
    }

    private String buildParams(SendQueueEntity entity) throws Exception {
        StringBuffer bf = new StringBuffer();
        bf.append("?un=").append(info.getAccount());
        bf.append("&pw=").append(info.getPassword());
        bf.append("&da=").append(entity.getPhone());
        bf.append("&sm=").append(URLEncoder.encode(entity.getContent(), "utf-8"));
        bf.append("&dc=").append(this.DC);
        bf.append("&rd=").append(this.RD);
        bf.append("&tf=").append(this.TF);
        bf.append("&sa=").append(entity.getAccessNumber());
        return bf.toString();
    }

    @Override
    public boolean notifyStatus(NotifyQueueEntity entity) {
        try {
            String param = entity.getParam();
            logger.info("HaoboGateway notifyStatus param : {}", param);
            int status = SmsMsgStatusEnum.SEND_FAIL.index;
            Map<String, String> paramMap = JSON.parseObject(param, Map.class);
            String op = paramMap.get("op");
            //昊博回调特殊处理
            if (StringUtils.isBlank(op)) {
                Set<String> keys = paramMap.keySet();
                String firstKey = null;
                for (String key : keys) {
                    firstKey = key;
                    break;
                }
                logger.info("HaoboGateway notifyStatus warn : {}", firstKey);
                if (StringUtils.isBlank(firstKey)) {
                    return false;
                }
                paramMap = strToMap(firstKey);
            }
            op = paramMap.get("op");
            //是状态报告
            if (REPORT.equalsIgnoreCase(op)) {
                String remoteId = paramMap.get("id");
                String messageId = JedisService.hget(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId);
                JedisService.hdel(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId);
                String gatewayStatus = paramMap.get("rp");
                if (SUCCESS.equals(gatewayStatus)) {
                    status = SmsMsgStatusEnum.SEND_SUCCESS.index;
                }
                String result = paramMap.get("rp") + "-" + paramMap.get("su");
                if (StringUtils.isBlank(messageId)) {
                    logger.warn("HaoboGateway notifyStatus messageId is null params : {}", param);
                }
                receiveReport(status, messageId, result);
                return true;
            } else {
                //上行消息
                ReceiveMsgQueueEntity mo = new ReceiveMsgQueueEntity();
                mo.setGatewayId(entity.getGatewayId());
                mo.setParam(entity.getParam());
                return receiveMsg(mo);
            }
        } catch (Exception e) {
            logger.error("HaoboGateway notifyStatus error ! ", e);
            return false;
        }
    }

    private static Map<String, String> strToMap(String key) {
        Map<String, String> map = new HashMap<>();
        String[] split = key.split("&");
        for (String s : split) {
            map.put(s.split("=")[0], s.split("=")[1]);
        }
        return map;
    }

    @Override
    public boolean receiveMsg(ReceiveMsgQueueEntity entity) {
        try {
            String param = entity.getParam();
            logger.info("HaoboGateway receiveMsg param : {}", param);
            Map<String, Object> paramMap = JSON.parseObject(param, Map.class);
            SmsReceiveMessage smsReceiveMessage = new SmsReceiveMessage();
            String accessNumber = paramMap.get("da") + "";
            String extend = accessNumber.substring(accessNumber.length() - 3);
            String account = JedisService.get(String.format(JedisKey.SMS_EXTEND_ACCOUNT, extend));
            String phone = paramMap.get("sa") + "";
            String hex = paramMap.get("sm") + "";
            String dc = paramMap.get("dc") + "";
            smsReceiveMessage.setAccount(account);
            smsReceiveMessage.setAccessNumber(accessNumber);
            smsReceiveMessage.setCreateTime(new Date());
            smsReceiveMessage.setPhone(phone);
            String content;
            if (DCS[0].equals(dc)) {
                //dc=8为ucs2编码
                content = new String(Hex.decodeHex(hex.toCharArray()), "UnicodeBigUnmarked");
            } else if (DCS[1].equals(dc)) {
                //dc=15为HEX编码
                content = new String(Hex.decodeHex(hex.toCharArray()), "gbk");
            } else {
                content = new String(Hex.decodeHex(hex.toCharArray()), "UTF-8");
            }
            smsReceiveMessage.setContent(content);
            smsReceiveMessage.setMessageId(extend);
            receiveMessage(smsReceiveMessage);
            return true;
        } catch (Exception e) {
            logger.error("HaoboGateway receiveMsg error ! ", e);
        }
        return false;
    }

    @Override
    public int queryBalance() {
        try {
            String queryUrl = info.getServerAddr().replace("mt", "bi?") + "un=" + info.getAccount() +
                    "&pw=" + info.getPassword();
            String response = HttpClientUtil.doGet(queryUrl);
            logger.info("{}余额查询结果:{}", info.getName(), response);
            return Integer.parseInt(response.split("&")[1].split("=")[1]);
        } catch (Exception e) {
            logger.error("HaoboGateway queryBalance error ! ", e);
        }
        return 0;
    }


    @Override
    public boolean queryStatus() {
        try {
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("un", info.getAccount());
            paramMap.put("pw", URLEncoder.encode(info.getPassword(), "utf8"));
            //每次获取100条记录
            paramMap.put("fs", 100);
            //2：获取结果为JSON返回
            paramMap.put("rf", 2);
            String url = info.getServerAddr().replaceFirst("mt", "mo");
            logger.info("HaoboGateway queryStatus HttpClientUtil.doPost URL : {}", url);
            String jsonStr = HttpClientUtil.doPost(url, paramMap);
            logger.info("HaoboGateway queryStatus return Result : {}", jsonStr);
            Map jsonMap = JSON.parseObject(jsonStr, Map.class);
            boolean success = Boolean.parseBoolean(jsonMap.get("success").toString());
            if (success) {
                List<Map> listMap = (List<Map>) JSONArray.parse(jsonMap.get("data").toString());
                for (Map map : listMap) {
                    int status = SmsMsgStatusEnum.SEND_FAIL.index;
                    //是状态报告
                    if (REPORT.equalsIgnoreCase(map.get("op") + "")) {
                        String remoteId = map.get("id") + "";
                        String messageId = JedisService.hget(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId);
                        JedisService.hdel(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId);
                        String gatewayStatus = map.get("rp") + "";
                        if (SUCCESS.equals(gatewayStatus)) {
                            status = SmsMsgStatusEnum.SEND_SUCCESS.index;
                        }
                        String result = map.get("rp") + "" + "-" + map.get("su") + "";
                        if (StringUtils.isBlank(messageId)) {
                            logger.warn("HaoboGateway queryStatus messageId is null params : {}", map);
                        }
                        receiveReport(status, messageId, result);
                    } else {
                        //上行消息
                        ReceiveMsgQueueEntity mo = new ReceiveMsgQueueEntity();
                        mo.setParam(map.toString());
                        receiveMsg(mo);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("HaoboGateway queryStatus error ! ", e);
            return false;
        }
        return true;
    }
}
